#pragma once
#include "..\lib\container\List.h"
#include <string>
#include "Action.h"
#include <string>
#include "..\nodes\SpriteNode.h"
#include "..\base\Controller.h"
#include "..\nodes\TextNode.h"
#include "..\utils\StringUtils.h"

namespace ds {

class BasicMenuAction : public Action , MouseController {

//typedef std::map<std::string,ds::PlainTextNode*> TextNodeMap;
	typedef std::map<std::string,ds::TextNode*> TextNodeMap;

struct MousePointer {
	SHandle spriteHandle;
	bool active;
	Rect textureRect;
	Vec2 offset;
};
struct MenuLink {
	Vec2 pos;
	Vec2 extent;
	std::string text;
	int id;
	bool active;
	std::string nextAction;
	int eventID;
	Color linkColor;
	Color hoverColor;
	std::string textNodeName;
};

typedef std::vector<MenuLink> MenuLinks;

struct ImageLink {
	Vec2 pos;
	Vec2 extent;
	int id;
	SHandle spriteHandle;
	std::string nextAction;
	int eventID;
};

typedef std::vector<ImageLink> ImageLinks;

public:
	BasicMenuAction(const char* stateName,const std::string& materialName,const std::string& layerName);
	virtual ~BasicMenuAction() {}
	virtual bool onActivation() {
		setVisibility(true);
		return true;
	}
	virtual bool onDeactivation() {
		setVisibility(false);		
		return true;
	}	
	virtual void start() {
		m_Pressed = false;
		setActive(true);
		onActivation();
	}
	virtual void stop() {
		setActive(false);
		onDeactivation();
	}
	void setNextStateName(const std::string& next) {
		m_NextStateName = next;	
	}	
	void addSprite(const Vec2& pos,const Rect& rect) {
		m_Sprites->add(pos,rect);
	}	
	void createTextNode(const std::string& name,const std::string& fontResource) {
		TextNode* textNode = new TextNode(name,m_Material,fontResource);
		WorldLayer wl = gEngine->getWorld().getLayerByName(m_LayerName.c_str());
		gEngine->getWorld().attachNode(textNode,wl);
		m_TextNodeMap[name] = textNode;
	}
	int addText(const std::string& textNodeName,int x,int y,const std::string& txt,int specialIndex = -1) {
		return addText(textNodeName,Vec2(x,y),txt,specialIndex);		
	}
	void setText(const std::string& textNodeName,int index,int x,int y,const std::string& txt) {
		TextNode* tn = m_TextNodeMap[textNodeName];
		if ( tn != 0 ) {
			TextEntry tl = tn->getText(index);
			//if ( tl != 0 ) {
				//tl->text = txt;
			//}
			//tn->setText("Text"+string::to_string(index),Vec2(x,y),Color(1.0f,1.0f,1.0f,1.0f),"%s",txt.c_str());
		}
	}	
	int addText(const std::string& textNodeName,Vec2& pos,const std::string& txt,int specialIndex = -1,float scale = 1.0f) {
		int ret = -1;
		TextNode* tn = m_TextNodeMap[textNodeName];
		if ( tn != 0 ) {
			int cnt = specialIndex;
			if ( cnt == -1 ) {
				++m_TextCounter;
				cnt = m_TextCounter;
			}
			++m_TextCounter;
			tn->setText(cnt,pos,Color(1.0f,1.0f,1.0f,1.0f),txt,scale);
			ret = cnt;
		}
		return ret;
	}
	void addLink(int id,const std::string& textNodeName,int x,int y,int width,int height,const std::string& txt,const Color& color = Color(1.0f,1.0f,1.0f,1.0f),const std::string& nextAction = "",const Color& hoverColor = Color(0.7f,0.0f,0.0f,1.0f));
	void addImageLink(int id,int x,int y,const Rect& textureRect,int eventID = -1);
	void attachEvent(int id,int eventID);
	void setLinkColor(int id,const std::string& textNodeName,const Color& color);
	void setLinkState(int id,const std::string& textNodeName,bool state);
	virtual void onMouseOver(int id);
	virtual void onMouseOut(int id);
	virtual void onClicked(int id) {}
	void update(float elapsedTime);
	void OnButtonDown( int button ) {
		m_Pressed = true;
	}
	void OnButtonUp( int button );
	void setMouseOffset(int x,int y) {
		m_Offset = Vec2(x,y);
	}
	void setMousePointer(Rect textureRect);
private:
	//
	bool isInside(const Vec2& mousePos,MenuLink* menuLink) const;
	bool isInside(const Vec2& mousePos,ImageLink* imageLink) const;
	void handleAction(int id,int eventID,const std::string& nextAction = "");
	void setVisibility(bool visible);
	//
	std::string m_StateName;
	std::string m_LayerName;
	int m_TextCounter;
	SpriteNode* m_Sprites;
	std::string m_Material;
	std::string m_NextStateName;
	TextNodeMap m_TextNodeMap;	
	MenuLinks m_Links;
	ImageLinks m_ImageLinks;
	MousePointer m_MousePointer;
	int m_SelectedID;
	Vec2 m_Offset;
	bool m_Pressed;
};

}

